package org.threebitsoftware.tbb.module.vcard;

import java.io.FileInputStream;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JPanel;

import net.sf.vcard4j.java.AddressBook;
import net.sf.vcard4j.java.VCard;
import net.sf.vcard4j.java.type.ADR;
import net.sf.vcard4j.java.type.EMAIL;
import net.sf.vcard4j.java.type.N;
import net.sf.vcard4j.java.type.PHOTO;
import net.sf.vcard4j.java.type.TEL;
import net.sf.vcard4j.parser.DomParser;

import org.threebitsoftware.tbb.dao.*;
import org.threebitsoftware.tbb.module.fileio.FileImportInterface;
import org.w3c.dom.Document;

import com.sun.org.apache.xerces.internal.dom.DocumentImpl;

public class VCardImporter implements FileImportInterface {

	@Override
	public Contact[] parseFile(String myStrFilePath) throws Exception {
		
		String company = "";
		String first = "";
		String last = "";
		String middle = "";
		String prefix = "";
		String suffix = "";
		String title = "";
		Vector<Contact> vectorContacts = new Vector<Contact> ();

		
		try {

			DomParser parser = new DomParser();
			
			Document document = new DocumentImpl();
			
			parser.parse(new FileInputStream(myStrFilePath), document);
			
			AddressBook addressBook = new AddressBook(document);
			
			
			for (Iterator vcards = addressBook.getVCards(); vcards.hasNext(); ) {
				
				VCard vcard = (VCard) vcards.next();
				N name = (N) vcard.getTypes("N").next();
				
				//prefix First middle. Last
				prefix = name.getPrefix();
				first = name.getGiven();
				middle = name.getOther();
				last = name.getFamily();
				suffix = name.getSuffix();
				
				Vector<Address> vectorAddress = getAddressesFromVCard(vcard);
				Vector<EmailAddress> vectorEmail = getEmailAddressesFromVCard(vcard);
				Vector<PhoneNumber> phoneNumber = getPhoneNumbersFromVCard(vcard);
				byte[] photo = getPhotoFromVCard(vcard);
						
				Contact aNewContact = new Contact (first, last, middle, suffix, prefix, company, title, true);

				if (vectorAddress != null) {
					aNewContact.setAddresses(vectorAddress);
				}
				
				if (vectorEmail != null) {
					aNewContact.setEmails(vectorEmail);
				}
				
				if (phoneNumber != null) {
					aNewContact.setPhoneNumbers(phoneNumber);
				}
				
				if (photo != null) {
					aNewContact.setPhoto(photo);
				}
				
				vectorContacts.add(aNewContact);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}

		return (vectorToArray (vectorContacts)); 
	}

	@Override
	public JPanel getGUI() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getMergeClassName() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean iHaveMyOwnGUI() {
		// TODO Auto-generated method stub
		return false; 
	}
		
	private Vector<Address> getAddressesFromVCard (VCard contact) {
		Vector<Address> physicalAddresses = null;
		boolean notYetAllocated = true;
		
		for (Iterator addresses=contact.getTypes("ADR"); addresses.hasNext(); ) {

			if (notYetAllocated) {
				physicalAddresses = new Vector<Address> ();
				notYetAllocated = false;
			}
	
			ADR address = (ADR) addresses.next();
			String streetStr1 = address.getStreet();
			String streetStr2 = address.getPobox();
			String streetStr3 = address.getExtadd();
			String countryStr = address.getCountry();
			String zipCodeStr = address.getPcode();
			String provinceStr = address.getRegion();
			String cityStr = address.getLocality();
			StringBuffer strBuf = new StringBuffer();

			if (((ADR.Parameters) address.getParameters()).containsTYPE(ADR.Parameters.TYPE_HOME)) {
				strBuf.append("Home");	
			}

			if (((ADR.Parameters) address.getParameters()).containsTYPE(ADR.Parameters.TYPE_WORK)) {
				strBuf.append("Work");	
			}
			
			if (((ADR.Parameters) address.getParameters()).containsTYPE(ADR.Parameters.TYPE_PREF)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Preferred");
			}
			
			String addressDesc = strBuf.toString();
			
			Address physicalAddress = new Address(streetStr1, streetStr2, streetStr3,
					countryStr, zipCodeStr, provinceStr, cityStr, addressDesc);
			
			physicalAddresses.add(physicalAddress);
		}
		return physicalAddresses;
	}
		
	private Vector<EmailAddress> getEmailAddressesFromVCard (VCard contact) {
		Vector<EmailAddress> emailAddresses = null;
		boolean notYetAllocated = true;
		
		for (Iterator emails=contact.getTypes("EMAIL"); emails.hasNext(); ) {

			if (notYetAllocated) {
				emailAddresses = new Vector<EmailAddress> ();
				notYetAllocated = false;
			}
	
			EMAIL email = (EMAIL) emails.next();
			String emailStr = email.get();
			StringBuffer strBuf = new StringBuffer();

			if (((EMAIL.Parameters) email.getParameters()).containsTYPE(EMAIL.Parameters.TYPE_PREF)) {
				strBuf.append("Preferred");	
			}
			
			String emailDesc = strBuf.toString();
			
			EmailAddress emailAddress = new EmailAddress(emailStr, emailDesc);
			
			emailAddresses.add(emailAddress);
		}
		return emailAddresses;
	}
	
	private Vector<PhoneNumber> getPhoneNumbersFromVCard (VCard contact) {
		Vector<PhoneNumber> phoneNumbers = null;
		boolean notYetAllocated = true;
		
		for (Iterator tels=contact.getTypes("TEL"); tels.hasNext(); ) {

			if (notYetAllocated) {
				phoneNumbers = new Vector<PhoneNumber> ();
				notYetAllocated = false;
			}
			
			TEL tel = (TEL) tels.next();
			String phoneStr = tel.get();
			StringBuffer strBuf = new StringBuffer();

			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_HOME)) {
				strBuf.append("Home");	
			}

			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_WORK)) {
				strBuf.append("Work");	
			}
			
			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_BBS)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("BBS");
			}

			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_CAR)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Car");	
			}
			
			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_CELL)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Cell");	
			}

			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_FAX)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Fax");	
			}
						
			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_PAGER)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Pager");	
			}
			
			if (((TEL.Parameters) tel.getParameters()).containsTYPE(TEL.Parameters.TYPE_VOICE)) {
				if (strBuf.length() != 0) {
					strBuf.append(";");
				}
				strBuf.append("Voice");	
			}
			
			String phoneDesc = strBuf.toString();
			
			PhoneNumber phoneNumber = new PhoneNumber(phoneStr, phoneDesc);
			
			phoneNumbers.add(phoneNumber);
		}
		return phoneNumbers;
	}
	
	private byte[] getPhotoFromVCard (VCard contact) {
		byte[] myContactPhoto = null;
		
		for (Iterator photos=contact.getTypes("PHOTO"); photos.hasNext(); ) {

			PHOTO photo = (PHOTO) photos.next();
			String photoStr = photo.get();
			
			myContactPhoto = photoStr.getBytes();
			break;
		}

		
		return myContactPhoto;
	}

	private Contact[] vectorToArray (Vector<Contact> vectorOfContacts) {
		
		int sizeOfVector = vectorOfContacts.size();
		Contact [] arrayOfContacts = null;
		
		if (sizeOfVector > 0) {
			int contactIndex = 0;
			
			arrayOfContacts = new Contact[sizeOfVector];
			
			for (Contact contact : vectorOfContacts) {
				arrayOfContacts [contactIndex] = contact;
				contactIndex++;
			}
		}
		return arrayOfContacts;
	}

}
